#include "XORoom.h"

#include "FKLogger.h"

#include "FKUser.h"

#include "FKActor.h"
#include "XOArea.h"
#include "XOSection.h"

#include "FKRoomInterface.h"
#include "XOWorld.h"

FK_EVENTS(XORoom){
}

XORoom::XORoom(FKRoom* room,qint32 objectID):FKRoom(room,objectID){
	FK_CBEGIN
	FK_CONSTRUCTOR
    setModel(new FKActorsModel(this));
    _field=0;
	FK_CEND
}

XORoom::~XORoom(){
	FK_DBEGIN
	FK_DESTRUCTOR
	FK_DEND
}

void XORoom::customInitialization(){
}

void XORoom::customDeinitialization(){
}

void XORoom::loadCore(){
    loadActors();
    _field=new XOArea(this);
    for(int i=0;i<3;++i){
        for(int j=0;j<3;++j){
            XOSection* s=new XOSection(this);
            float size=s->size();
            connect(s,SIGNAL(clicked(QPoint)),SLOT(sectionClicked(QPoint)));
            s->move(QVector3D(-size+size*i,size-size*j,-1));
            _field->addSection(i,j,s);
//            s->applyUpdates();
            foreach(FKActor* a, _actors){
                s->allowControlBy(a);
            }
        }
    }
//    _field->move(QVector3D(0,0,-1));
//    _field->applyUpdates();
    foreach(FKActor* a, _actors){
        a->setTotalWatching(_field);
        a->setActive(false);
    }
    connect(_actors.at(0),SIGNAL(won(FKActor*)),_actors.at(1),SLOT(lose()));
    connect(_actors.at(1),SIGNAL(won(FKActor*)),_actors.at(0),SLOT(lose()));
}

void XORoom::initStart(){
    _currentActor=qrand() % 2;
    qint32 nextActor=(_currentActor ? 0 : 1);
    _marks.clear();
    _marks[_currentActor]=X_OWNER;
    _marks[nextActor]=O_OWNER;
    FKActor* curActorRef=_actors[_currentActor];
    FKActor* nextActorRef=_actors[nextActor];
    curActorRef->setActive(true);
    nextActorRef->setActive(false);
    _field->reset();
}

void XORoom::loadUser(FKUser* user){
    user->setTotalWatching(getObject(actorsModel()->actorForUserID(user->getID())));
}

void XORoom::sectionClicked(QPoint p){
    _field->nextSection(p)->setOwner(_marks[_currentActor]);
    _field->nextSection(p)->applyUpdates();
    if(checkWin(p)){
        _actors.at(_currentActor)->win();
    }else{
        nextTurn();
    }
}

void XORoom::nextTurn(){
    qint32 nextActor=(_currentActor ? 0 : 1);
    _actors[_currentActor]->setActive(false);
    _actors[nextActor]->setActive(true);
    _currentActor=nextActor;
}

bool XORoom::checkWin(const QPoint& p){
    qint8 curSymbol=_marks[_currentActor];
    QList<QPoint> directions;
    directions<<QPoint(1,1)<<QPoint(0,1)<<QPoint(1,0)<<QPoint(1,-1);
    foreach (QPoint direction, directions) {
        if(_field->countMarks(p,direction,curSymbol)==3){
            return true;
        }
    }
    return false;
}

bool XORoom::startCondition(){
    return _users.count()==2;
}

FKWorldReferent* XORoom::worldClass()const{
    return new XOWorld();
}

FKRoomInterface* XORoom::interfaceClass()const{
    return new FKRoomInterface();
}
